package com.zenithmind.chat.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.chat.mapper.ChatGroupMapper;
import com.zenithmind.chat.mapper.ChatGroupMemberMapper;
import com.zenithmind.chat.pojo.dto.ChatGroupDTO;
import com.zenithmind.chat.pojo.entity.ChatGroup;
import com.zenithmind.chat.pojo.entity.ChatGroupMember;
import com.zenithmind.chat.pojo.query.ChatGroupQuery;
import com.zenithmind.chat.pojo.vo.ChatGroupVO;
import com.zenithmind.chat.pojo.vo.ChatUserVO;
import com.zenithmind.chat.service.ChatGroupService;
import com.zenithmind.chat.service.ChatMessageService;
import com.zenithmind.common.context.UserContext;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.utils.BeanCopyUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 聊天群组服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class ChatGroupServiceImpl extends ServiceImpl<ChatGroupMapper, ChatGroup> implements ChatGroupService {

    private final ChatGroupMemberMapper memberMapper;
    private final ChatMessageService messageService;

    @Override
    public PageResult<ChatGroupVO> getGroupPage(ChatGroupQuery query) {
        Page<ChatGroup> page = query.toPage();

        LambdaQueryWrapper<ChatGroup> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(query.getName()), ChatGroup::getName, query.getName())
               .like(StringUtils.hasText(query.getDescription()), ChatGroup::getDescription, query.getDescription())
               .eq(query.getType() != null, ChatGroup::getType, query.getType())
               .eq(query.getStatus() != null, ChatGroup::getStatus, query.getStatus())
               .eq(StringUtils.hasText(query.getCourseId()), ChatGroup::getCourseId, query.getCourseId())
               .eq(StringUtils.hasText(query.getProjectId()), ChatGroup::getProjectId, query.getProjectId())
               .orderByDesc(ChatGroup::getCreateTime);

        IPage<ChatGroup> result = page(page, wrapper);

        List<ChatGroupVO> voList = result.getRecords().stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());

        return PageResult.of(voList, result.getTotal(), result.getCurrent(), result.getSize());
    }

    @Override
    public ChatGroupVO getGroupById(String id, String userId) {
        ChatGroup group = getById(id);
        if (group == null) {
            throw new BusinessException("群组不存在");
        }

        ChatGroupVO groupVO = convertToVO(group);
        
        // 获取用户在群组中的信息
        if (StringUtils.hasText(userId)) {
            LambdaQueryWrapper<ChatGroupMember> memberWrapper = new LambdaQueryWrapper<>();
            memberWrapper.eq(ChatGroupMember::getGroupId, id)
                        .eq(ChatGroupMember::getUserId, userId)
                        .eq(ChatGroupMember::getIsDeleted, 0);

            ChatGroupMember member = memberMapper.selectOne(memberWrapper);
            if (member != null && member.getStatus() == 1) {
                groupVO.setUserRole(member.getRole());
                groupVO.setIsJoined(true);
                groupVO.setIsMuted(member.getMuteEndTime() != null &&
                                  member.getMuteEndTime().isAfter(LocalDateTime.now()));
                groupVO.setMuteEndTime(member.getMuteEndTime());
            } else {
                groupVO.setIsJoined(false);
            }
            
            // 获取最新消息
            groupVO.setLastMessage(messageService.getLatestMessage(id, userId));
            
            // 获取未读消息数
            groupVO.setUnreadCount(messageService.getUnreadMessageCount(id, userId));
        }
        
        return groupVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String createGroup(ChatGroupDTO groupDTO, String userId) {
        // 验证参数
        validateGroupDTO(groupDTO);
        
        // 创建群组
        ChatGroup group = BeanCopyUtils.copyBean(groupDTO, ChatGroup.class);
        group.setOwnerId(userId);
        group.setOwnerName(UserContext.getUsername());
        group.setMemberCount(1);
        group.setStatus(groupDTO.getStatus() != null ? groupDTO.getStatus() : 1);
        group.setMaxMembers(groupDTO.getMaxMembers() != null ? groupDTO.getMaxMembers() : 500);
        group.setAllowInvite(groupDTO.getAllowInvite() != null ? groupDTO.getAllowInvite() : 1);
        group.setNeedApproval(groupDTO.getNeedApproval() != null ? groupDTO.getNeedApproval() : 0);
        group.setIsPublic(groupDTO.getIsPublic() != null ? groupDTO.getIsPublic() : 0);
        group.setSort(groupDTO.getSort() != null ? groupDTO.getSort() : 0);
        
        // 处理标签
        if (!CollectionUtils.isEmpty(groupDTO.getTags())) {
            group.setTags(String.join(",", groupDTO.getTags()));
        }
        
        save(group);
        
        // 添加群主为成员
        ChatGroupMember ownerMember = new ChatGroupMember();
        ownerMember.setGroupId(group.getId());
        ownerMember.setUserId(userId);
        ownerMember.setUserName(UserContext.getUsername());
        ownerMember.setRole(1); // 群主
        ownerMember.setStatus(1); // 正常
        ownerMember.setJoinTime(LocalDateTime.now());
        ownerMember.setLastActiveTime(LocalDateTime.now());
        memberMapper.insert(ownerMember);
        
        // 添加初始成员
        if (!CollectionUtils.isEmpty(groupDTO.getMemberIds())) {
            addInitialMembers(group.getId(), groupDTO.getMemberIds(), userId);
        }
        
        // 发送系统消息
        messageService.sendSystemMessage(group.getId(),
            String.format("群组\"%s\"创建成功", group.getName()), 6);
        
        log.info("用户 {} 创建群组: {}", userId, group.getName());
        return group.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateGroup(String id, ChatGroupDTO groupDTO, String userId) {
        ChatGroup group = getById(id);
        if (group == null) {
            throw new BusinessException("群组不存在");
        }
        
        // 检查权限（群主或管理员）
        if (!checkUserPermission(id, userId, 2)) {
            throw new BusinessException("无权限修改群组信息");
        }
        
        // 更新群组信息
        group.setName(groupDTO.getName());
        group.setDescription(groupDTO.getDescription());
        group.setAvatar(groupDTO.getAvatar());
        group.setType(groupDTO.getType());
        group.setStatus(groupDTO.getStatus());
        group.setMaxMembers(groupDTO.getMaxMembers());
        group.setAllowInvite(groupDTO.getAllowInvite());
        group.setNeedApproval(groupDTO.getNeedApproval());
        group.setIsPublic(groupDTO.getIsPublic());
        group.setAnnouncement(groupDTO.getAnnouncement());
        group.setCourseId(groupDTO.getCourseId());
        group.setProjectId(groupDTO.getProjectId());
        group.setSort(groupDTO.getSort());

        // 处理标签
        if (!CollectionUtils.isEmpty(groupDTO.getTags())) {
            group.setTags(String.join(",", groupDTO.getTags()));
        }
        
        updateById(group);
        
        // 发送系统消息
        messageService.sendSystemMessage(id, 
            "群组信息已更新", 6);
        
        log.info("用户 {} 更新了群组: {}", userId, id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteGroup(String id, String userId) {
        ChatGroup group = getById(id);
        if (group == null) {
            throw new BusinessException("群组不存在");
        }
        
        // 检查权限（只有群主可以删除群组）
        if (!Objects.equals(group.getOwnerId(), userId)) {
            throw new BusinessException("只有群主可以删除群组");
        }
        
        // 软删除群组
        removeById(id);
        
        // 删除所有成员
        LambdaQueryWrapper<ChatGroupMember> memberWrapper = new LambdaQueryWrapper<>();
        memberWrapper.eq(ChatGroupMember::getGroupId, id);
        memberMapper.delete(memberWrapper);
        
        // 发送系统消息
        messageService.sendSystemMessage(id,
            String.format("群组\"%s\"已解散", group.getName()), 6);
        
        log.info("用户 {} 删除了群组: {}", userId, id);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteGroupsBatch(List<String> ids, String userId) {
        if (CollectionUtils.isEmpty(ids)) {
            return false;
        }
        
        for (String id : ids) {
            deleteGroup(id, userId);
        }
        
        return true;
    }

    @Override
    public List<ChatGroupVO> getUserGroups(String userId, Integer status) {
        // 通过群组成员表查询用户加入的群组
        LambdaQueryWrapper<ChatGroupMember> memberWrapper = new LambdaQueryWrapper<>();
        memberWrapper.eq(ChatGroupMember::getUserId, userId)
                    .eq(status != null, ChatGroupMember::getStatus, status)
                    .orderByDesc(ChatGroupMember::getJoinTime);

        List<ChatGroupMember> members = memberMapper.selectList(memberWrapper);

        if (CollectionUtils.isEmpty(members)) {
            return List.of();
        }

        // 获取群组ID列表
        List<String> groupIds = members.stream()
            .map(ChatGroupMember::getGroupId)
            .collect(Collectors.toList());

        // 查询群组信息
        LambdaQueryWrapper<ChatGroup> groupWrapper = new LambdaQueryWrapper<>();
        groupWrapper.in(ChatGroup::getId, groupIds)
                   .eq(ChatGroup::getIsDeleted, 0)
                   .orderByDesc(ChatGroup::getCreateTime);

        List<ChatGroup> groups = list(groupWrapper);

        return groups.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    @Override
    public List<ChatGroupVO> getPublicGroups(ChatGroupQuery query) {
        LambdaQueryWrapper<ChatGroup> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatGroup::getIsPublic, 1) // 公开群组
               .eq(ChatGroup::getStatus, 1) // 正常状态
               .eq(ChatGroup::getIsDeleted, 0)
               .like(StringUtils.hasText(query.getName()), ChatGroup::getName, query.getName())
               .eq(query.getType() != null, ChatGroup::getType, query.getType())
               .orderByDesc(ChatGroup::getMemberCount)
               .orderByDesc(ChatGroup::getCreateTime);

        if (query.getLimit() != null && query.getLimit() > 0) {
            wrapper.last("LIMIT " + query.getLimit());
        }

        List<ChatGroup> groups = list(wrapper);

        return groups.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean joinGroup(String groupId, String userId, String inviterId) {
        ChatGroup group = getById(groupId);
        if (group == null) {
            throw new BusinessException("群组不存在");
        }
        
        if (group.getStatus() == 0) {
            throw new BusinessException("群组已禁用");
        }
        
        // 检查是否已是成员
        LambdaQueryWrapper<ChatGroupMember> checkWrapper = new LambdaQueryWrapper<>();
        checkWrapper.eq(ChatGroupMember::getGroupId, groupId)
                   .eq(ChatGroupMember::getUserId, userId)
                   .eq(ChatGroupMember::getStatus, 1)
                   .eq(ChatGroupMember::getIsDeleted, 0);

        long memberExists = memberMapper.selectCount(checkWrapper);
        if (memberExists > 0) {
            throw new BusinessException("您已是群组成员");
        }

        // 检查群组人数限制
        LambdaQueryWrapper<ChatGroupMember> countWrapper = new LambdaQueryWrapper<>();
        countWrapper.eq(ChatGroupMember::getGroupId, groupId)
                   .eq(ChatGroupMember::getStatus, 1)
                   .eq(ChatGroupMember::getIsDeleted, 0);

        long memberCount = memberMapper.selectCount(countWrapper);
        if (memberCount >= group.getMaxMembers()) {
            throw new BusinessException("群组人数已满");
        }
        
        // 创建成员记录
        ChatGroupMember member = new ChatGroupMember();
        member.setGroupId(groupId);
        member.setUserId(userId);
        member.setUserName(UserContext.getUsername());
        member.setRole(3); // 普通成员
        member.setStatus(group.getNeedApproval() == 1 ? 3 : 1); // 需要审核则为待审核状态
        member.setJoinTime(LocalDateTime.now());
        member.setLastActiveTime(LocalDateTime.now());
        member.setInviterId(inviterId);
        
        memberMapper.insert(member);
        
        // 更新群组成员数
        if (member.getStatus() == 1) {
            updateGroupMemberCount(groupId, 1);
        }
        
        // 发送系统消息
        String message = StringUtils.hasText(inviterId) ? 
            String.format("%s 邀请 %s 加入群组", getInviterName(inviterId), UserContext.getUsername()) :
            String.format("%s 加入群组", UserContext.getUsername());
        messageService.sendSystemMessage(groupId, message, 6);
        
        log.info("用户 {} 加入群组: {}", userId, groupId);
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean leaveGroup(String groupId, String userId, String reason) {
        ChatGroup group = getById(groupId);
        if (group == null) {
            throw new BusinessException("群组不存在");
        }
        
        // 群主不能直接退出，需要先转让群主
        if (Objects.equals(group.getOwnerId(), userId)) {
            throw new BusinessException("群主不能退出群组，请先转让群主");
        }
        
        // 更新成员状态为已退出
        LambdaQueryWrapper<ChatGroupMember> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatGroupMember::getGroupId, groupId)
               .eq(ChatGroupMember::getUserId, userId);
        
        ChatGroupMember member = memberMapper.selectOne(wrapper);
        if (member == null) {
            throw new BusinessException("您不是群组成员");
        }
        
        member.setStatus(0); // 已退出
        member.setExitReason(reason);
        member.setExitTime(LocalDateTime.now());
        memberMapper.updateById(member);
        
        // 更新群组成员数
        updateGroupMemberCount(groupId, -1);
        
        // 发送系统消息
        messageService.sendSystemMessage(groupId, 
            String.format("%s 退出群组", UserContext.getUsername()), 6);
        
        log.info("用户 {} 退出群组: {}", userId, groupId);
        return true;
    }

    // 私有方法
    private void validateGroupDTO(ChatGroupDTO groupDTO) {
        if (!StringUtils.hasText(groupDTO.getName())) {
            throw new BusinessException("群组名称不能为空");
        }
        
        if (groupDTO.getType() == null || groupDTO.getType() < 1 || groupDTO.getType() > 4) {
            throw new BusinessException("群组类型无效");
        }
        
        if (groupDTO.getMaxMembers() != null && (groupDTO.getMaxMembers() < 2 || groupDTO.getMaxMembers() > 1000)) {
            throw new BusinessException("群组最大成员数必须在2-1000之间");
        }
    }

    private String getGroupTypeText(Integer type) {
        switch (type) {
            case 1: return "普通群";
            case 2: return "课程群";
            case 3: return "项目群";
            case 4: return "系统群";
            default: return "未知";
        }
    }

    private void addInitialMembers(String groupId, List<String> memberIds, String inviterId) {
        List<ChatGroupMember> members = new ArrayList<>();
        
        for (String memberId : memberIds) {
            if (Objects.equals(memberId, inviterId)) {
                continue; // 跳过群主
            }
            
            ChatGroupMember member = new ChatGroupMember();
            member.setGroupId(groupId);
            member.setUserId(memberId);
            member.setUserName("用户" + memberId); // 这里应该从用户服务获取真实姓名
            member.setRole(3); // 普通成员
            member.setStatus(1); // 正常
            member.setJoinTime(LocalDateTime.now());
            member.setLastActiveTime(LocalDateTime.now());
            member.setInviterId(inviterId);
            
            members.add(member);
        }
        
        if (!CollectionUtils.isEmpty(members)) {
            for(ChatGroupMember member : members) {
                memberMapper.insert(member);
            }
            updateGroupMemberCount(groupId, members.size());
        }
    }

    private String getInviterName(String inviterId) {
        // 这里应该从用户服务获取用户姓名
        return "用户" + inviterId;
    }

    @Override
    public Boolean checkUserPermission(String groupId, String userId, Integer requiredRole) {
        LambdaQueryWrapper<ChatGroupMember> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatGroupMember::getGroupId, groupId)
               .eq(ChatGroupMember::getUserId, userId)
               .eq(ChatGroupMember::getStatus, 1)
               .eq(ChatGroupMember::getIsDeleted, 0);

        ChatGroupMember member = memberMapper.selectOne(wrapper);
        if (member == null) {
            return false;
        }

        // 角色权限检查：1-群主 > 2-管理员 > 3-普通成员
        return member.getRole() <= requiredRole;
    }

    // 其他方法的实现...
    @Override
    public Boolean inviteUsers(String groupId, List<String> userIds, String inviterId) {
        // TODO: 实现邀请用户逻辑
        return true;
    }

    @Override
    public Boolean removeMembers(String groupId, List<String> userIds, String operatorId, String reason) {
        // TODO: 实现移除成员逻辑
        return true;
    }

    @Override
    public Boolean setAdmins(String groupId, List<String> userIds, String operatorId) {
        // TODO: 实现设置管理员逻辑
        return true;
    }

    @Override
    public Boolean removeAdmins(String groupId, List<String> userIds, String operatorId) {
        // TODO: 实现取消管理员逻辑
        return true;
    }

    @Override
    public Boolean muteMembers(String groupId, List<String> userIds, Integer muteMinutes, String operatorId) {
        // TODO: 实现禁言逻辑
        return true;
    }

    @Override
    public Boolean unmuteMembers(String groupId, List<String> userIds, String operatorId) {
        // TODO: 实现解除禁言逻辑
        return true;
    }

    @Override
    public Boolean transferOwnership(String groupId, String newOwnerId, String currentOwnerId) {
        // TODO: 实现转让群主逻辑
        return true;
    }

    @Override
    public Boolean updateAnnouncement(String groupId, String announcement, String operatorId) {
        // TODO: 实现更新群公告逻辑
        return true;
    }

    @Override
    public PageResult<ChatUserVO> getGroupMembers(String groupId, Integer status, Integer role, String keyword, Integer pageNum, Integer pageSize) {
        // TODO: 实现获取群组成员逻辑
        return PageResult.of(List.of(), 0L);
    }

    @Override
    public String createCourseGroup(String courseId, String courseName, String teacherId) {
        // TODO: 实现创建课程群逻辑
        return null;
    }

    @Override
    public String createProjectGroup(String projectId, String projectName, String leaderId) {
        // TODO: 实现创建项目群逻辑
        return null;
    }

    @Override
    public Object getGroupStatistics() {
        // 使用MyBatis-Plus查询统计信息
        LambdaQueryWrapper<ChatGroup> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ChatGroup::getIsDeleted, 0);

        long totalGroups = count(wrapper);

        wrapper.clear();
        wrapper.eq(ChatGroup::getIsDeleted, 0)
               .eq(ChatGroup::getStatus, 1);
        long activeGroups = count(wrapper);

        wrapper.clear();
        wrapper.eq(ChatGroup::getIsDeleted, 0)
               .eq(ChatGroup::getIsPublic, 1);
        long publicGroups = count(wrapper);

        // 创建统计对象（简化版）
        final long finalTotalGroups = totalGroups;
        final long finalActiveGroups = activeGroups;
        final long finalPublicGroups = publicGroups;

        return new Object() {
            public final Long totalGroups = finalTotalGroups;
            public final Long activeGroups = finalActiveGroups;
            public final Long publicGroups = finalPublicGroups;
            public final Long courseGroups = 0L;
            public final Long projectGroups = 0L;
            public final Long todayGroups = 0L;
        };
    }

    @Override
    public Boolean updateGroupStatus(String id, Integer status, String operatorId) {
        // TODO: 实现更新群组状态逻辑
        return true;
    }

    /**
     * 转换为VO对象
     */
    private ChatGroupVO convertToVO(ChatGroup group) {
        ChatGroupVO vo = BeanCopyUtils.copyBean(group, ChatGroupVO.class);

        // 设置类型文本
        vo.setTypeText(getGroupTypeText(group.getType()));
        vo.setStatusText(group.getStatus() == 1 ? "启用" : "禁用");

        // 设置标签列表
        if (StringUtils.hasText(group.getTags())) {
            vo.setTags(List.of(group.getTags().split(",")));
        }

        return vo;
    }

    /**
     * 更新群组成员数量
     */
    private void updateGroupMemberCount(String groupId, Integer count) {
        ChatGroup group = getById(groupId);
        if (group != null) {
            group.setMemberCount(Math.max(0, group.getMemberCount() + count));
            updateById(group);
        }
    }
}
